package com.ruoyi.system.controller;

import cn.hutool.core.date.DateTime;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.system.domain.Message;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;


/**
 * @author: CJJ
 * @date: 2024/06/26/09:55
 * @desc:
 */

@RestController
@RequestMapping("/bot")
public class TSBotController extends BaseController {

    private final Map<String, String> responses;

    public TSBotController() {
        responses = new HashMap<>();

        // 预订管理功能
        responses.put("酒店", "您可以在我们平台上查找并预订各类酒店。请提供入住日期、离开日期、人数和房间类型。");
        responses.put("机票", "我们提供便捷的机票预订服务。请提供出发地、目的地、出发日期和乘客信息。");
        responses.put("景点门票", "您可以预订各大景点的门票。请提供景点名称、日期、票数和选项（如优惠券）。");

        // 用户管理功能
        responses.put("注册", "欢迎注册！请提供您的用户名、密码和邮箱地址完成注册。");
        responses.put("登录", "请提供您的用户名和密码进行登录。");
        responses.put("修改个人信息", "您可以在个人资料页面修改您的个人信息，如联系方式和地址。");
        responses.put("历史订单", "您可以在个人资料页面查看您的订单历史记录。");

        // 行程规划功能
        responses.put("选择旅行目的地", "我们提供多种旅行目的地供您选择，您可以查看各地景点和交通信息。");
        responses.put("景点介绍", "您可以在我们平台上查看各大景点的详细介绍和推荐。");
        responses.put("地图导航", "使用我们的地图导航功能，轻松规划您的旅行路线。除此之外，您还可以使用Google Maps、百度地图或者导航软件帮助您找到目的地。");
        responses.put("路线规划", "根据您的选择，我们会为您提供最佳的行程路线规划建议。");

        // 景点信息管理功能
        responses.put("景点搜索", "您可以在我们的平台上搜索您感兴趣的景点信息。");
        responses.put("开放时间", "各景点的开放时间会在我们的平台上进行更新和公布。");
        responses.put("门票价格", "您可以查看各景点的门票价格，并进行比较和选择。");

        // 客户服务与支持功能
        responses.put("在线客服", "我们提供24小时在线客服支持，您可以实时与客服人员进行沟通和咨询。");
        responses.put("留言功能", "您可以留言给我们的客服团队，我们会尽快给您回复。");
        responses.put("投诉处理", "如果您有任何不满或建议，您可以通过我们的投诉渠道进行反馈。");

        // 数据分析和报告功能
        responses.put("预订记录分析", "我们会分析您的预订记录，以提供更好的服务和推荐。");
        responses.put("偏好信息分析", "我们会分析您的偏好信息，以个性化推荐和定制化服务。");
        responses.put("生成统计报告", "根据收集的数据，我们会定期生成统计报告和洞察分析，以帮助您了解市场趋势。");

        // 添加问题和回答的对应关系
        responses.put("你好", "您好，请问有什么可以帮助您的吗");
        responses.put("服务", "我们为您提供24小时在线服务。");
        responses.put("订单查询", "请提供订单号，我来为您查询。");
        responses.put("目的地推荐", "您可以考虑去巴黎、东京或者纽约等知名旅游目的地。");
        responses.put("交通信息", "您可以选择搭乘飞机、火车或汽车前往目的地。");
        responses.put("住宿建议", "您可以选择酒店、民宿或青年旅舍作为住宿。");
        responses.put("美食推荐", "您可以尝试当地的特色菜肴，如意大利面、寿司或者饺子。");
        responses.put("购物指南", "您可以去当地的商场、街市或者特色小店购物。");
        responses.put("签证问题", "请提前了解目的地国家的签证要求，并准备相关材料。");
        responses.put("天气信息", "您可以查看天气预报来准备合适的服装和行程安排。");

        // 更多问题和回答的对应关系
        responses.put("旅游季节", "不同地区的旅游季节不同，您可以根据目的地的气候情况选择合适的时间。");
        responses.put("语言问题", "您可以学习一些基本的当地语言或者使用翻译工具来沟通。");
        responses.put("紧急联系", "请记录目的地国家的紧急联系电话，以备不时之需。");
        responses.put("特别注意事项", "请遵守当地的法律法规，并尊重当地的风俗习惯。");
        responses.put("活动推荐", "您可以参加当地的文化节、体育赛事或者户外探险活动。");
        responses.put("小费", "在某些国家，给服务人员小费是一种常规礼仪，您可以根据具体情况决定是否给小费。");
        responses.put("退税政策", "一些国家允许外国游客在购物时退还部分税款，您可以了解目的地的退税政策。");
        responses.put("手机网络", "请确认您的手机是否支持漫游，并了解当地的手机网络覆盖情况。");

        // 添加更多问题和回答的对应关系
        responses.put("游览时间", "建议您在早上或者傍晚时分游览景点，避开人流高峰。");
        responses.put("儿童", "许多景点和酒店提供儿童友好设施，您可以在预订时咨询相关信息。");
        responses.put("医疗", "建议您购买旅行保险，以便在需要时能够得到及时的医疗服务。");
        responses.put("预算", "建议您在出发前制定好旅行预算，并尽量遵守，以避免不必要的支出。");
        responses.put("电源插座", "不同国家的电源插座类型不同，建议您携带合适的转换插头和电源适配器。");
        responses.put("本地礼仪", "了解当地的礼仪习惯是尊重当地文化的一种表现，可以让您的旅行更加愉快。");
        responses.put("季节性", "一些目的地会有特定的季节性活动，您可以根据您的兴趣和时间安排参加。");
        responses.put("自驾游", "自驾游前请了解目的地的交通法规和道路状况，并确保租车合法合规。");
        responses.put("导游", "您可以在旅行社或当地旅游信息中心预订导游服务，以更深入地了解目的地。");
        responses.put("安全", "保护个人财物和随身携带的重要文件是旅行中的基本常识，请随时保持警惕。");
        
        responses.put("注册账号", "您可以在首页点击注册按钮，然后填写您的信息完成注册。");
        responses.put("我忘记了密码怎么办", "您可以尝试找回密码，或者联系我们的客服帮助您重置密码。");
        responses.put("联系客服", "您可以通过我们的在线聊天系统与客服联系，或者拨打我们的客服电话。");
        responses.put("你们的服务时间是多久", "我们的服务时间是每周一到周五，早上9点到晚上6点。");
        responses.put("有没有免费试用期", "是的，我们有免费的30天试用期供您体验。");
        responses.put("你们的产品有什么特点", "我们的产品注重用户体验，功能全面，支持多平台使用。");
        responses.put("登录账号", "您可以在首页点击登录按钮，然后输入您的用户名和密码进行登录。");
        responses.put("查看订单状态", "您可以在个人中心或者订单页面查看您的订单状态。");
        responses.put("修改信息", "您可以在个人中心里找到编辑个人信息的选项，然后修改您需要更新的信息。");
        responses.put("支付订单", "您可以在结算页面选择您希望的支付方式，并完成支付操作。");
        responses.put("取消订单", "您可以在订单详情页面找到取消订单的选项，然后按照提示进行操作。");
        responses.put("联系技术支持", "您可以通过在线聊天系统与技术支持联系，或者发送电子邮件至技术支持邮箱。");
        responses.put("提出退款申请", "您可以在订单详情页面找到申请退款的选项，然后填写退款申请表格并提交。");

        responses.put("如何预订酒店", "您可以在我们的平台上选择目的地、日期、房间类型和人数，然后查看实时可用性和价格，完成预订。");
        responses.put("如何预订机票", "您可以输入起始地点、目的地、出发日期和返回日期，然后选择航班和座位，完成预订。");
        responses.put("如何购买景点门票", "您可以选择目的地和日期，查看景点门票的价格和开放时间，然后选择购买。");

        // 用户管理功能相关问题和回答
        responses.put("如何注册账户", "您可以点击注册按钮，填写必要信息并创建个人账户。");
        responses.put("如何登录账户", "您可以在首页点击登录，输入您的用户名和密码进行登录。");
        responses.put("如何修改个人信息", "在个人中心页面，您可以找到编辑个人信息的选项，修改您的个人资料。");
        responses.put("如何查看订单历史", "在个人中心页面，您可以查看您的历史订单记录和详细信息。");

        // 行程规划功能相关问题和回答
        responses.put("如何规划旅行行程", "您可以使用我们的行程规划工具，选择目的地、景点、交通方式等，系统将为您提供详细的行程安排和导航路线。");
        responses.put("如何查看景点介绍", "在我们的平台上，您可以查看每个景点的详细介绍、开放时间和门票价格。");
        responses.put("如何使用地图导航", "在景点详情页面，您可以查看地图导航功能，帮助您找到景点的具体位置和周边设施。");

        // 景点信息管理功能相关问题和回答
        responses.put("如何搜索特定的景点", "您可以使用我们的搜索功能，输入景点名称或关键词，系统将为您筛选和排序相关的景点信息。");

        // 客户服务与支持功能相关问题和回答
        responses.put("如何联系在线客服", "您可以点击网页右下角的在线聊天按钮，与客服进行实时聊天或留言，我们将尽快回复您的问题。");
        responses.put("如何提交投诉", "如果您有任何投诉或意见，您可以在我们的网站上找到投诉和反馈页面，填写相关信息并提交。");

        // 数据分析和报告功能相关问题和回答
        responses.put("如何查看我的预订记录", "在个人中心页面，您可以查看您的预订记录和历史行为。");
        responses.put("如何获取个性化推荐", "我们会根据您的历史预订记录和偏好信息，为您提供个性化的景点推荐和定制化的服务。");
    }

    @GetMapping("/quest")
    public R<Message> getResponse(@RequestParam("question") String question) {
        TSBotController bot = new TSBotController();
        Message message = new Message();
        message.setCreateTime(DateTime.now());
        message.setSendUser("bot");
        message.setHandle(UUID.randomUUID().toString());
        message.setIsRead("0");
        // 遍历问题和回答的映射，查找匹配的问题并返回对应的回答
        try {
            String matchedResponse = findBestMatch(question);
            if (matchedResponse != null) {
                message.setContent(matchedResponse);
                return R.ok(message, "回答成功!");
            } else {
                message.setContent("抱歉，我暂时无法理解您的问题。可以尝试人工客服解答~");
                return R.ok(message, "找不到回答");
            }
        } catch (Exception e) {
            return R.fail(1, e.getMessage());
        }
    }

    // 通过杰卡德相似系数算法找到最佳匹配答案
    private String findBestMatch(String question) {
        String bestMatch = null;
        int bestScore = Integer.MIN_VALUE;

        // Iterate over each response and calculate a score based on similarity
        for (Map.Entry<String, String> entry : responses.entrySet()) {
            String key = entry.getKey();
            String response = entry.getValue();

            // Calculate similarity score between question and key
            int score = calculateSimilarityScore(question, key);

            // Update best match if current score is higher
            if (score > bestScore) {
                bestScore = score;
                bestMatch = response;
            }
        }

        // Only return the best match if score meets a certain threshold
        // Here, we use a threshold of 50 as an example, adjust as needed
        if (bestScore >= 50) {
            return bestMatch;
        } else {
            return null; // Return null if no match meets the threshold
        }
    }

    private int calculateSimilarityScore(String question, String key) {
        // Convert both question and key to lowercase for case insensitivity

        // Calculate similarity score (example: using Jaccard index)
        double intersection = getJaccardIndex(question, key);
        // Scale the similarity score to an integer range
        int score = (int) (intersection * 100);

        return score;
    }

    // 计算Jaccard Index杰卡德相似系数
    public static double getJaccardIndex(String str1, String str2) {
        Set<Character> set1 = new HashSet<>();
        Set<Character> set2 = new HashSet<>();

        // 将字符串中的字符添加到集合中（忽略重复字符）
        for (char c : str1.toCharArray()) {
            set1.add(c);
        }

        for (char c : str2.toCharArray()) {
            set2.add(c);
        }

        // 计算Jaccard Index
        return calculateJaccardIndex(set1, set2);
    }

    // 计算Jaccard Index的辅助方法
    private static double calculateJaccardIndex(Set<Character> set1, Set<Character> set2) {
        Set<Character> intersection = new HashSet<>(set1);
        intersection.retainAll(set2); // 求交集

        Set<Character> union = new HashSet<>(set1);
        union.addAll(set2); // 求并集

        // 计算Jaccard Index

        return (double) intersection.size() / union.size();
    }

}

